package cn.maihe.elg.operation.centers.guogu.handler.service;

import cn.maihe.elg.operation.centers.guogu.channel.GuoGuCenterInterfaceServiceImpl;
import cn.maihe.elg.operation.centers.guogu.config.GuoGuCenterInfosConfig;
import cn.maihe.elg.operation.centers.guogu.dto.GuoGuBaseRespDTO;
import cn.maihe.elg.operation.centers.guogu.dto.channel.resp.GuoGuCusQueryRespData;
import cn.maihe.elg.operation.centers.guogu.dto.handler.req.GuoGuInsureApplyReq;
import cn.maihe.elg.operation.centers.guogu.dto.handler.resp.GuoGuInsureApplyResp;
import cn.maihe.elg.operation.centers.guogu.dto.handler.resp.GuoGuInsureApplyRespData;
import cn.maihe.elg.operation.centers.guogu.enums.FileTypeNameEnum;
import cn.maihe.elg.operation.centers.guogu.handler.GuoGuCenterTradeService;
import cn.maihe.elg.operation.centers.hymake.dto.handler.FilePushReqDTO;
import cn.maihe.elg.operation.centers.supports.CenterTradeContext;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.bo.AcceptOrderBO;
import cn.maihe.elg.operation.model.dto.InnerBaseResp;
import cn.maihe.elg.operation.model.enums.AcceptOrderStatus;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import cn.maihe.elg.operation.model.enums.CenterProviderEnum;
import cn.maihe.elg.operation.model.enums.GuaranteeCategory;
import cn.maihe.elg.operation.model.enums.GuaranteeType;
import cn.maihe.elg.operation.model.enums.IDType;
import cn.maihe.elg.operation.model.enums.InstitutionOrgCodeEnum;
import cn.maihe.elg.operation.model.enums.TradeType;
import cn.maihe.elg.operation.model.enums.UserStatusEnum;
import cn.maihe.elg.operation.model.enums.UserType;
import cn.maihe.elg.operation.repository.entity.AcceptOrderInfoDO;
import cn.maihe.elg.operation.repository.entity.BidCustomerDO;
import cn.maihe.elg.operation.repository.entity.GuaranteeInstitutionDO;
import cn.maihe.elg.operation.repository.entity.ProjectInfoDO;
import cn.maihe.elg.operation.repository.entity.UserDO;
import cn.maihe.elg.operation.service.business.BidCustomerService;
import cn.maihe.elg.operation.service.business.ProjectInfoService;
import cn.maihe.elg.operation.service.order.AcceptOrderInfoService;
import cn.maihe.elg.operation.supports.system.ElgResourceService;
import cn.maihe.elg.operation.utils.CreateGuaranteeUtil;
import cn.maihe.elg.operation.utils.DateUtil;
import cn.maihe.elg.operation.utils.IdGenerate;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Description 投保信息推送
 * @Author SSX
 * @Date 2025/03/18
 */
@CenterTradeService(
        provider = CenterProviderEnum.GUOGU,
        centerNo = CenterNoEnum.GUOGU,
        tradeType = TradeType.insure_apply,
        reqClass = GuoGuInsureApplyReq.class,
        respClass = GuoGuInsureApplyResp.class
)
@Slf4j
public class GuoGuInsureApplyService extends GuoGuCenterTradeService<GuoGuInsureApplyReq, GuoGuInsureApplyResp> {
    public GuoGuInsureApplyService(GuoGuCenterInfosConfig guoGuCenterInfosConfig) {
        super(guoGuCenterInfosConfig);
    }

    @Resource
    private AcceptOrderInfoService acceptOrderInfoService;
    @Resource
    private ElgResourceService elgResourceService;
    @Resource
    private ProjectInfoService projectInfoService;
    @Resource
    private GuoGuCenterInterfaceServiceImpl guoGuCenterInterfaceServiceImpl;
    @Resource
    private BidCustomerService bidCustomerService;

    @Override
    protected void verifyParam(CenterTradeContext<GuoGuInsureApplyReq, GuoGuInsureApplyResp> context) {
        super.verifyParam(context);
        GuoGuInsureApplyReq req = context.getReq();
        String orderNo = req.getApplyno();
        boolean exists = acceptOrderInfoService.existsCenterOrderId(context.getCenterId(), orderNo);
        Assert.isTrue(!exists, () -> "中心订单编号已存在");
    }

    @Override
    public GuoGuInsureApplyResp processService(CenterTradeContext<GuoGuInsureApplyReq, GuoGuInsureApplyResp> context) {

        AcceptOrderBO acceptOrderBO = this.parseApplyGuaranteeInfo(context);

        acceptOrderBO = acceptOrderInfoService.saveAcceptOrderBO(acceptOrderBO);

        GuoGuInsureApplyResp resp = buildResp(acceptOrderBO, context.getReq());
        return resp;
    }

    private GuoGuCusQueryRespData queryCusInfo(String clientId, CenterNoEnum centerNoEnum, String applyno) {
        InnerBaseResp<GuoGuCusQueryRespData> innerBaseResp = guoGuCenterInterfaceServiceImpl.queryCusInfo(clientId, centerNoEnum, applyno);
        if (innerBaseResp.getRespCode().isSuccess()) {
/*            try {
                ValidateUtil.validate(innerBaseResp.getData());
            } catch (Exception e) {
                log.error("查询客户信息 >> [{}] 参数校验失败:{}", centerNoEnum.getCenterName(), e.getMessage(), e);
                throw GuoGuException.of(GuoGuRespCodeEnum.FAILURE, "参数校验失败:" + e.getMessage(), e);
            }*/
            return innerBaseResp.getData();
        }
        throw new RuntimeException(innerBaseResp.getMessage());
    }

    private GuoGuInsureApplyResp buildResp(AcceptOrderBO acceptOrderBO, GuoGuInsureApplyReq req) {
        GuoGuInsureApplyResp resp = GuoGuBaseRespDTO.success("受理成功", GuoGuInsureApplyResp.class);
        //投标企业是否已提交企业认证资料且已审核通过
        GuoGuInsureApplyRespData data = new GuoGuInsureApplyRespData();
        data.setAmount(new BigDecimal(req.getAmount()));
        data.setTradeNo(req.getApplyno());
        data.setPayUrl(elgResourceService.buildElgFrontUrl("/#/autoLogin?mobile=" + acceptOrderBO.getUserDO().getUsername() + "&ordersn=" + acceptOrderBO.getAcceptOrderInfo().getAcceptOrderNo()));
        resp.setData(data);
        return resp;
    }

    private List<FilePushReqDTO.FileInfo> buildFileInfo(GuoGuCusQueryRespData queryCusInfoData) {
        List<FilePushReqDTO.FileInfo> fileInfos = new ArrayList<>();
        if (Objects.isNull(queryCusInfoData)) {
            return fileInfos;
        }
        if (StringUtils.isNotBlank(queryCusInfoData.getLegalPersonCardFront())) {
            FilePushReqDTO.FileInfo legalCertFileInfo = new FilePushReqDTO.FileInfo();
            legalCertFileInfo.setFileTypeName(FileTypeNameEnum.TYPE05.getFileTypeName());
            legalCertFileInfo.setFileType(FileTypeNameEnum.TYPE05.getFileTypeName());
            legalCertFileInfo.setUrl(queryCusInfoData.getLegalPersonCardFront());
            fileInfos.add(legalCertFileInfo);
        }

        if (StringUtils.isNotBlank(queryCusInfoData.getLegalPersonCardBack())) {
            FilePushReqDTO.FileInfo legalOppositeCertFileInfo = new FilePushReqDTO.FileInfo();
            legalOppositeCertFileInfo.setFileTypeName(FileTypeNameEnum.TYPE06.getFileTypeName());
            legalOppositeCertFileInfo.setFileType(FileTypeNameEnum.TYPE06.getFileTypeName());
            legalOppositeCertFileInfo.setUrl(queryCusInfoData.getLegalPersonCardBack());
            fileInfos.add(legalOppositeCertFileInfo);
        }

        if (StringUtils.isNotBlank(queryCusInfoData.getBusinessLicensePic())) {
            FilePushReqDTO.FileInfo lFileInfo = new FilePushReqDTO.FileInfo();
            lFileInfo.setUrl(queryCusInfoData.getBusinessLicensePic());
            lFileInfo.setFileTypeName(FileTypeNameEnum.TYPE03.getFileTypeName());
            fileInfos.add(lFileInfo);
        }


        if (StringUtils.isNotBlank(queryCusInfoData.getCertifications())) {
            List<String> certifications = new ArrayList<>();
            try {
                certifications = JSON.parseArray(queryCusInfoData.getCertifications(), String.class);
            } catch (Exception e) {
                log.warn("certifications parse error");
            }

            if (!CollectionUtils.isEmpty(certifications)) {
                FilePushReqDTO.FileInfo qFileInfo = new FilePushReqDTO.FileInfo();
                qFileInfo.setUrl(certifications.get(0));
                qFileInfo.setFileTypeName(FileTypeNameEnum.TYPE04.getFileTypeName());
                fileInfos.add(qFileInfo);
            }
        }

        if (StringUtils.isNotBlank(queryCusInfoData.getExtSignInsureBook())) {
            FilePushReqDTO.FileInfo sqFileInfo = new FilePushReqDTO.FileInfo();
            sqFileInfo.setUrl(queryCusInfoData.getExtSignInsureBook());
            sqFileInfo.setFileTypeName(FileTypeNameEnum.TYPE02.getFileTypeName());
            fileInfos.add(sqFileInfo);
        }

        return fileInfos;
    }

    /**
     * 解析 受理的清单信息
     */
    private AcceptOrderBO parseApplyGuaranteeInfo(CenterTradeContext<GuoGuInsureApplyReq, GuoGuInsureApplyResp> context) {
        GuoGuInsureApplyReq req = context.getReq();
        String clientId = context.getAttr("clientId");
        GuoGuCusQueryRespData queryCusInfoData = queryCusInfo(clientId, context.getCenterNoEnum(), req.getApplyno());
        // 测试
//        GuoGuCusQueryRespData queryCusInfoData = new GuoGuCusQueryRespData();
//        String fileUrl = "https://b.zol-img.com.cn/sjbizhi/images/11/1080x1920/1592967802496.jpg";
//        queryCusInfoData.setCertifications(fileUrl);
//        queryCusInfoData.setExtSignInsureBook("https://img.shetu66.com/2023/06/27/1687828512585698.png");
//        queryCusInfoData.setBusinessLicensePic("https://file.51pptmoban.com/d/file/2022/09/13/b2d85362febcf895e78916e0696f1a59.jpg");
//        queryCusInfoData.setLegalPersonName("张三");
//        queryCusInfoData.setLegalPersonCardNo("123345678901");
//        queryCusInfoData.setLegalPersonCardBack("https://img.shetu66.com/2022/08/31/1661927013462861.jpg");
//        queryCusInfoData.setLegalPersonCardFront("https://img.shetu66.com/2023/06/21/1687311446374252.png");

        List<FilePushReqDTO.FileInfo> fileInfos = buildFileInfo(queryCusInfoData);

        long centerId = context.getCenterId();
        long orgId = context.getOrgId();

        InstitutionOrgCodeEnum institutionOrgCodeEnum = InstitutionOrgCodeEnum.resolve(context.getOrgCode());
        GuaranteeInstitutionDO institutionDO = getInstitutionIdByCode(institutionOrgCodeEnum);
        String acceptOrderNo = IdGenerate.genAcceptOrderNo(context.getCenterNoEnum());

        ProjectInfoDO projectInfoDO = this.buildProjectInfo(clientId, req, centerId, orgId);
        BidCustomerDO bidCustomerDO = this.buildBidCustomerInfo(context.getCenterNoEnum(), clientId, req, centerId, orgId);
        UserDO userDO = this.buildUserInfo(req, centerId, orgId);

        AcceptOrderInfoDO acceptOrderInfoDO = this.buildAcceptOrderInfo(clientId, acceptOrderNo, req, centerId, orgId, institutionDO);
        //计算保费
        String feeRate = this.getCurCenterInfo(context).getFeeRate();
        acceptOrderInfoDO.setFeeRate(feeRate);
        //Long minFeeYuan = this.getCurCenterInfo(context).getMinFeeYuan();
        //acceptOrderInfoDO.setGuaranteeFee(this.calcGuaranteeFee(projectInfoDO.getBidBond(), feeRate, minFeeYuan));
        //古国的保费不用计算
        acceptOrderInfoDO.setGuaranteeFee(yuan2fenLong(req.getAmount()));
        AcceptOrderBO orderBO = AcceptOrderBO.builder().centerId(centerId).orgId(orgId).fileInfos(fileInfos)
                .acceptOrderInfo(acceptOrderInfoDO).projectInfo(projectInfoDO).bidCustomer(bidCustomerDO).userDO(userDO).build();

        //默认投标保函类别;
        orderBO.setGuaranteeCategory(GuaranteeCategory.BID);
        //默认担保公司担保类型;
        orderBO.setGuaranteeType(GuaranteeType.GUARANTEE);

        orderBO.setInstitutionOrgCodeEnum(institutionOrgCodeEnum);
        orderBO.setIsInnerApply(false);

        //出函机构赋值
        acceptOrderInfoDO.setInstitutionId(institutionDO.getId());
        acceptOrderInfoDO.setGuaranteeType(orderBO.getGuaranteeType().getTypeStr());
        acceptOrderInfoDO.setGuaranteeCategory(orderBO.getGuaranteeCategory().getCategoryStr());


        return orderBO;
    }


    private AcceptOrderInfoDO buildAcceptOrderInfo(String clientId, String acceptOrderNo, GuoGuInsureApplyReq req, long centerId, long orgId, GuaranteeInstitutionDO institutionDO) {
        return AcceptOrderInfoDO.builder()
                .centerId(centerId).orgId(orgId)
                .guaranteeNo(IdGenerate.genGuaranteeNo(institutionDO.getInstitutionCode()))
                .centerOrderId(req.getApplyno())
                .centerOrderTime(DateUtil.getDatetime())
                .acceptOrderNo(acceptOrderNo)
                .projectName(req.getProjectname())
                .sectionName(req.getBiaoduanname())
                .bidCustomerName(req.getBiddername())
                //当前投标期限保证金截止时间
                //.bidIndate(DateUtil.parseDate(req.getBzjendtime(), "yyyy-MM-dd HH:mm:ss"))TODO
                .guaranteeType(null)//'保函类型'
                .guaranteeCategory(null) //'保函品种'
                .templateId(null)//'报价模板主键id'
                .feeRate(null)
                .guaranteeFee(null)//'保费金额分'
                .status(AcceptOrderStatus.WAIT_PAY.getStatus())
                .guaranteeTime(null)
                .projectId(null)//  '投保项目主键id' 关联保存时统一设置
                .bidCustomerId(null)// '投保客户主键id'
                .institutionId(null) //'开函机构主键'
                .attachmentId(null)//
                .applyOrderNo(null)
                .invoiceFlag(null)
                .invoiceId(null)
                .warnFlag(0).warnContent(null)
                .gmtCreate(Date.from(Instant.now()))
                .clientId(clientId)
                .build();
    }

    private BidCustomerDO buildBidCustomerInfo(CenterNoEnum centerNoEnum, String clientId, GuoGuInsureApplyReq req, long centerId, long orgId) {
        // 其他信息通过 企业认证补充页面收集
        BidCustomerDO bidCustomerDO = BidCustomerDO.builder().bankName(req.getBankUserName()).bankName(req.getBankName()).bankCardNum(req.getBankCardNum())
                .centerId(centerId).orgId(orgId)
                .bidderName(req.getBiddername())
                .bidderCreditCode(req.getBiddercode())
                .bidderContactName(req.getBidderContactName())
                .bidderContactTel(req.getBidderContactTel())
                .bidderContactIdcardType(IDType.ID_CARD.getType())
                .bidderContactIdcard(null)
                .bidderAddress(req.getBidderAddress())
                .bidderRegAddress(req.getBidderAddress())
                .bidderEamil(null)
                .legalPersonName(null)
                .legalPersonTel(null)
                .legalPersonIdcardType(IDType.ID_CARD.getType())
                .legalPersonIdcard(null)
                .enableAutoApprove(0) //'是否自动审批 0否 1是',
                .blacklistFlag(0) //'是否黑名单 0后 1是',*/
                .gmtCreate(Date.from(Instant.now())).build();

        BidCustomerDO dbDo = bidCustomerService.getByCreditCode(req.getBiddercode(), null);

        if (!CreateGuaranteeUtil.isSuiXing(centerNoEnum, clientId)) {
            if (Objects.isNull(dbDo)) {
                bidCustomerDO.setCompleteFlag(0);
            } else {
                if (!Objects.equals(dbDo.getStatus(), 1)) {
                    bidCustomerDO.setCompleteFlag(0);
                }
            }
        }

        return bidCustomerDO;
    }

    private UserDO buildUserInfo(GuoGuInsureApplyReq req, long centerId, long orgId) {
        return UserDO.builder()
                .umLogin("0")
                .followId(req.getBiddercode())
                .username(req.getBiddercode())
                .mobileNo(null)//改成统一社会信用代码登录
                .name(req.getBiddername())
                .type(UserType.BIDDER.getType())
                .status(UserStatusEnum.NORMAL.name())
                .orgCode("-1")
                .gmtCreate(new Date())
                .gmtModified(new Date())
                .build();
    }

    private ProjectInfoDO buildProjectInfo(String clientId, GuoGuInsureApplyReq req, long centerId, long orgId) {
        ProjectInfoDO projectInfoDO = ProjectInfoDO.builder()
                .centerId(centerId).orgId(orgId)
                .projectCode(req.getProjectno()).projectName(req.getProjectname())
                .sectionCode(req.getBiaoduanno()).sectionName(req.getBiaoduanname())
                .tenderer(req.getZbr())
                .tendererCreditCode(req.getZbrorgnum())
                .tendererBankOpenbank(req.getTendereropenbank())
                .tendererBankCode(req.getTendererbankcode())
                .tendererBankAccount(req.getTendererbankaccount())
                .tendererContact(req.getTenderercontact())
                .tendererContactTel(req.getTenderercontacttel())
                .cityCode(req.getCitycode())
                .tenderProjectType(req.getProjecttype())
                .secondCategoryCode(req.getSecondCategoryCode())
                .validPeriod(Integer.valueOf(req.getTbyxq()))//投标有效期（单位：天）
                .bidBond(yuan2fenLong(req.getBzjamount()))
                .tenderNoticeUrl(req.getTendernoticeurl())
                .tenderFileUrl(req.getTenderfileurl())
                .tenderFileMd5(genTenderFileMd5(req.getBiaoduanno(), req.getBiaoduanname(), centerId, orgId, req.getTenderfileurl()))//'招标方文件md5校验值'
                .tendererAddress(req.getZbraddress())
                .remark(null)//无
                .warnFlag(0)// '预警标识0正常 1出函机构无法受理该项目',
                .sourceFlag(0)// '信息来源0自动 1手动',
                .gmtCreate(Date.from(Instant.now()))
                .build();
        if (CreateGuaranteeUtil.isSuiXing(centerNoEnum, clientId)) {
            projectInfoDO.setBidOpenTime(DateUtil.parseDate(req.getKaibiaotime(), "yyyy-MM-dd HH:mm:ss"));
        } else {
            JSONObject ciphertext = new JSONObject();
            ciphertext.put("kaibiaotime", req.getKaibiaotime());
            ciphertext.put("zbfiledate", req.getZbfiledate());
            projectInfoDO.setCiphertext(ciphertext.toJSONString());
        }

        projectInfoDO.setTemplateId(CreateGuaranteeUtil.getGuoGuTemplateId(centerNoEnum,clientId,req.getSecondCategoryCode()));
        return projectInfoDO;
    }

    private String genTenderFileMd5(String sectionCode, String sectionName, Long centerId, Long orgId, String tenderFileUrl) {
        String tenderFileMd5 = null;
        try {
            if (!StringUtils.isEmpty(tenderFileUrl)) {
                ProjectInfoDO projectInfo = projectInfoService.getBySectionCode(sectionCode, sectionName, centerId, orgId);
                if (projectInfo == null || StringUtils.isEmpty(projectInfo.getTenderFileMd5())) {
                    //download file
                    Path tmpPath = elgResourceService.downloadByURL(tenderFileUrl);

                    String relativePath = elgResourceService.transferAndSaveFile(tmpPath, "ofd", "tenderFile", "标段" + sectionCode + "招标文件");
                    Path savePath = elgResourceService.getAbsolutePath(relativePath);
                    tenderFileMd5 = elgResourceService.getFileMD5AsHex(savePath);
                    try {
                        Files.deleteIfExists(tmpPath);
                    } catch (IOException e) {
                        log.error("删除临时招标文件异常：{}", e.getMessage(), e);
                    }
                } else {
                    tenderFileMd5 = projectInfo.getTenderFileMd5();
                }
            }
        } catch (Exception e) {
            log.error("下载招标文件失败：{}", e.getMessage(), e);
        }
        return tenderFileMd5;
    }


}
